home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Special 23 / AMIGAplus Sonderheft 23 (2000)(Falke)(DE)[!].iso / Updates / Datatypes / JPEG-DT35 / Source / dispatcher.c < prev    next >
C/C++ Source or Header  |  1999-11-14  |  7KB  |  297 lines

  1. #include <clib/alib_protos.h>
  2. #include <pragma/datatypes_lib.h>
  3. #include <pragma/dos_lib.h>
  4. #include <pragma/exec_lib.h>
  5. #include <pragma/graphics_lib.h>
  6. #include <pragma/intuition_lib.h>
  7. #include <pragma/jpeg_lib.h>
  8. #include <pragma/utility_lib.h>
  9. #include <render/renderhooks.h>
  10. #include <datatypes/pictureclass.h>
  11. #include <exec/memory.h>
  12. #include <intuition/icclass.h>
  13. #include <string.h>
  14. #include "class.h"
  15.  
  16. struct Arg1
  17. {
  18. long *dct,*scale,*quality,*smooth,gray,prog;
  19. };
  20.  
  21. ULONG SaveJPEG(IClass *cl,Object *obj,dtWrite *msg);
  22.  
  23. void ReadPrefs(Data *data)
  24. {
  25. char *var;
  26. data->dct=0;
  27. data->scale=1;
  28. data->quality=75;
  29. data->smooth=0;
  30. data->gray=0;
  31. data->prog=0;
  32. if(var=(char *)AllocVec(512,0))
  33.     {
  34.     if(GetVar("ENV:DataTypes/jpeg.prefs",var,512,LV_VAR|GVF_GLOBAL_ONLY)>=0)
  35.         {
  36.         RDArgs *rdargs;
  37.       if(rdargs=(RDArgs *)AllocDosObject(DOS_RDARGS,0))
  38.             {
  39.             RDArgs *args;
  40.             Arg1 para;
  41.             rdargs->RDA_Source.CS_Buffer=var;
  42.             rdargs->RDA_Source.CS_Length=strlen(var);
  43.             rdargs->RDA_Source.CS_CurChr=0;
  44.             memset(¶,0,sizeof(Arg1));
  45.             if(args=ReadArgs("DCT/A/N,SCALE/A/N,QUALITY/A/N,SMOOTH/A/N,GRAY/S,PROGRESSIVE/S",(long *)¶,rdargs))
  46.                 {
  47.                 data->dct=*para.dct;
  48.                 if(data->dct<0) data->dct=0;
  49.                 else if(data->dct>2) data->dct=2;
  50.                 data->scale=*para.scale;
  51.                 if(data->scale<0) data->scale=0;
  52.                 else if(data->scale>3) data->scale=3;
  53.                 data->scale=1<<data->scale;
  54.                 data->quality=*para.quality;
  55.                 if(data->quality<1) data->quality=1;
  56.                 else if(data->quality>100) data->quality=100;
  57.                 data->smooth=*para.smooth;
  58.                 if(data->smooth<0) data->smooth=0;
  59.                 else if(data->smooth>100) data->smooth=100;
  60.                 data->gray=para.gray;
  61.                 data->prog=para.prog;
  62.                 FreeArgs(args);
  63.                 }
  64.             FreeDosObject(DOS_RDARGS,rdargs);
  65.             }
  66.         }
  67.     FreeVec(var);
  68.     }
  69. }
  70.  
  71. struct JPEGINFO
  72. {
  73. Object *obj;
  74. UBYTE *buffer;
  75. UWORD d,gray;
  76. };
  77.  
  78. static void _getline(UBYTE *scanline,ULONG y,ULONG numb,JPEGINFO *info)
  79. {
  80. if(info->gray) DoMethod(info->obj,PDTM_WRITEPIXELARRAY,scanline,PBPAFMT_GREY8,numb,0,y,numb,1);
  81. else
  82.     {
  83.     ULONG w=numb/3;
  84.     if(info->d>8) DoMethod(info->obj,PDTM_WRITEPIXELARRAY,scanline,PBPAFMT_RGB,numb,0,y,w,1);
  85.     else
  86.         {
  87.         register ULONG i;
  88.         register UBYTE *p1,*p2;
  89.         p1=info->buffer+w*y*4;
  90.         p2=scanline;
  91.         for(i=0;i<w;i++,p1+=4,p2+=3)
  92.             {
  93.             p1[1]=p2[0];
  94.             p1[2]=p2[1];
  95.             p1[3]=p2[2];
  96.             }
  97.         }
  98.     }
  99. }
  100.  
  101. static ULONG getline(register __a0 UBYTE *scanline,register __d0 ULONG line,register __d1 ULONG numb,register __a1 void *userdata)
  102. {
  103. _getline(scanline,line-1,numb,(JPEGINFO *)userdata);
  104. return 0;
  105. }
  106.  
  107. static void FillBMHD(Object *obj,BitMapHeader *bh,ULONG w,ULONG h,ULONG depth)
  108. {
  109. bh->bmh_Left=0;
  110. bh->bmh_Top=0;
  111. bh->bmh_Width=w;
  112. bh->bmh_Height=h;
  113. bh->bmh_PageWidth=w;
  114. bh->bmh_PageHeight=h;
  115. bh->bmh_Depth=depth;
  116. bh->bmh_Compression=cmpByteRun1;
  117. bh->bmh_XAspect=0;
  118. bh->bmh_YAspect=0;
  119. }
  120.  
  121. static ULONG GetBody_Gray(JPEGDecHandle *jph,BitMapHeader *bh,Object *obj,Data *data)
  122. {
  123. ULONG error=0;
  124. UBYTE *buffer;
  125. if(buffer=(UBYTE *)AllocBufferFromJPEG(jph,JPG_ScaleDenom,data->scale,TAG_END))
  126.     {
  127.     if(!DecompressJPEG(jph,JPG_DestRGBBuffer,buffer,JPG_ScaleDenom,data->scale,JPG_DCTMethod,data->dct,TAG_END))
  128.         {
  129.         DoMethod(obj,PDTM_WRITEPIXELARRAY,buffer,PBPAFMT_GREY8,bh->bmh_Width,0,0,bh->bmh_Width,bh->bmh_Height);
  130.         }
  131.     else error=ERROR_NO_FREE_STORE;
  132.     FreeJPEGBuffer(buffer);
  133.     }
  134. else
  135.     {
  136.     JPEGINFO info={0,0,8,1};
  137.     if(DecompressJPEG(jph,JPG_DecompressHook,getline,JPG_DecompressUserData,&info,JPG_ScaleDenom,data->scale,JPG_DCTMethod,data->dct,TAG_END)) error=ERROR_NO_FREE_STORE;
  138.     else error=ERROR_NO_FREE_STORE;
  139.     }
  140. return error;
  141. }
  142.  
  143. static ULONG GetBody_RGB(JPEGDecHandle *jph,BitMapHeader *bh,Object *obj,Data *data)
  144. {
  145. ULONG error=0;
  146. UBYTE *buffer;
  147. if(buffer=(UBYTE *)AllocBufferFromJPEG(jph,JPG_ScaleDenom,data->scale,TAG_END))
  148.     {
  149.     if(!DecompressJPEG(jph,JPG_DestRGBBuffer,buffer,JPG_ScaleDenom,data->scale,JPG_DCTMethod,data->dct,TAG_END))
  150.         DoMethod(obj,PDTM_WRITEPIXELARRAY,buffer,PBPAFMT_RGB,bh->bmh_Width*3,0,0,bh->bmh_Width,bh->bmh_Height);
  151.     else error=ERROR_NO_FREE_STORE;
  152.     FreeJPEGBuffer(buffer);
  153.     }
  154. else
  155.     {
  156.     JPEGINFO info={obj,0,24,0};
  157.     if(DecompressJPEG(jph,JPG_DecompressHook,getline,JPG_DecompressUserData,&info,JPG_ScaleDenom,data->scale,JPG_DCTMethod,data->dct,TAG_END)) error=ERROR_NO_FREE_STORE;
  158.     }
  159. return error;
  160. }
  161.  
  162. static ULONG GetPicture(IClass *cl,Object *obj)
  163. {
  164. ULONG error=0;
  165. long err;
  166. BPTR file;
  167. BitMapHeader *bh;
  168. GetDTAttrs(obj,DTA_Name,&bh,TAG_END);
  169. if(bh) SetDTAttrs(obj,0,0,DTA_ObjName,bh,TAG_END);
  170. GetDTAttrs(obj,DTA_Handle,&file,PDTA_BitMapHeader,&bh,TAG_END);
  171. if(bh)
  172.     {
  173.     JPEGDecHandle *jph;
  174.     if(!file)
  175.         {
  176.         GetDTAttrs(obj,DTA_SourceType,&err,TAG_END);
  177.         if(err!=DTST_RAM) return ERROR_REQUIRED_ARG_MISSING;
  178.         else return 0;
  179.         }
  180.     if(!AllocJPEGDecompress(&jph,JPG_SrcFile,file,TAG_END))
  181.         {
  182.         UBYTE colorspace;
  183.         ULONG w,h,bpp;
  184.         Data *data=(Data *)INST_DATA(cl,obj);
  185.         ReadPrefs(data);
  186.         if(!GetJPEGInfo(jph,JPG_Width,&w,JPG_Height,&h,JPG_ColourSpace,&colorspace,JPG_BytesPerPixel,&bpp,JPG_ScaleDenom,data->scale,TAG_END))
  187.             {
  188.             bh->bmh_Left=0;
  189.             bh->bmh_Top=0;
  190.             bh->bmh_Width=w;
  191.             bh->bmh_Height=h;
  192.             bh->bmh_PageWidth=w;
  193.             bh->bmh_PageHeight=h;
  194.             bh->bmh_Depth=(colorspace==JPCS_RGB)?24:8;
  195.             bh->bmh_Compression=cmpByteRun1;
  196.             bh->bmh_XAspect=0;
  197.             bh->bmh_YAspect=0;
  198.             SetDTAttrs(obj,0,0,DTA_ErrorNumber,&error,DTA_NominalHoriz,w,DTA_NominalVert,h,PDTA_SourceMode,PMODE_V43,PDTA_ModeID,0,TAG_END);
  199.             if(!error)
  200.                 {
  201.                 switch(colorspace)
  202.                     {
  203.                     case JPCS_GRAYSCALE:
  204.                         error=GetBody_Gray(jph,bh,obj,data);
  205.                         break;
  206.                     case JPCS_RGB:
  207.                         error=GetBody_RGB(jph,bh,obj,data);
  208.                         break;
  209.                     default:
  210.                         error=ERROR_NOT_IMPLEMENTED;
  211.                     }
  212.                 }
  213.             }
  214.         else error=DTERROR_INVALID_DATA;
  215.         }
  216.     else error=DTERROR_INVALID_DATA;
  217.     }
  218. else error=ERROR_NO_FREE_STORE;
  219. return error;
  220. }
  221.  
  222. static ULONG mNew(IClass *cl,Object *obj,opSet *msg)
  223. {
  224. TagItem *ti;
  225. if(ti=FindTagItem(DTA_SourceType,(((opSet *)msg)->ops_AttrList)))
  226.     {
  227.     if(ti->ti_Data!=DTST_FILE&&ti->ti_Data!=DTST_CLIPBOARD&&ti->ti_Data!=DTST_RAM)
  228.         {
  229.         SetIoErr(ERROR_OBJECT_WRONG_TYPE);
  230.         return 0;
  231.         }
  232.     }
  233. if(obj==(Object *)cl)
  234.     {
  235.     if(obj=(Object *)DoSuperMethodA(cl,obj,Msg(msg)))
  236.         {
  237.         ULONG error;
  238.         if(error=GetPicture(cl,obj))
  239.             {
  240.             SetIoErr(error);
  241.             CoerceMethod(cl,obj,OM_DISPOSE);
  242.             obj=0;
  243.             }
  244.         }
  245.     }
  246. else
  247.     {
  248.     SetIoErr(ERROR_NOT_IMPLEMENTED);
  249.     obj=0;
  250.     }
  251. return ULONG(obj);
  252. }
  253.  
  254. static ULONG mSet(IClass *cl,Object *obj,opSet *msg)
  255. {
  256. ULONG retval;
  257. if(retval=DoSuperMethodA(cl,obj,Msg(msg)))
  258.     {
  259.     RastPort *rp;
  260.     if(rp=ObtainGIRPort(msg->ops_GInfo))
  261.         {
  262.         DoMethod(obj,GM_RENDER,msg->ops_GInfo,rp,GREDRAW_UPDATE);
  263.         ReleaseGIRPort(rp);
  264.         retval=0;
  265.         }
  266.     }
  267. return retval;
  268. }
  269.  
  270. static ULONG mWrite(IClass *cl,Object *obj,dtWrite *msg)
  271. {
  272. return (msg->dtw_Mode==DTWM_IFF)?DoSuperMethodA(cl,obj,Msg(msg)):SaveJPEG(cl,obj,msg);
  273. }
  274.  
  275. extern "C" ULONG Dispatcher(IClass *cl,Object *obj,Msg msg)
  276. {
  277. ULONG retval;
  278. switch(msg->MethodID)
  279.     {
  280.     case OM_NEW:
  281.         retval=mNew(cl,obj,(opSet *)msg);
  282.         break;
  283.     case OM_UPDATE:
  284.         if(DoMethod(obj,ICM_CHECKLOOP)) break;
  285.     case OM_SET:
  286.         retval=mSet(cl,obj,(opSet *)msg);
  287.         break;
  288.     case DTM_WRITE:
  289.         retval=mWrite(cl,obj,(dtWrite *)msg);
  290.         break;
  291.     default:
  292.         retval=DoSuperMethodA(cl,obj,msg);
  293.         }
  294. return retval;
  295. }
  296.  
  297.